<template>
  <div id="app">
    <div class="calc-box">
      <input type="text" disabled :value="inputValue" />
      <ul>
        <li v-for="(item, i) in dataArr" :key="i" @click="btnClick(item)">
          <button>{{ item.text }}</button>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
export default {
  // 可复用组件
  data() {
    return {
      inputValue: "",
      arr: [], // 字符串中包含的运算符集合
      numArr: [], // 字符串中所有的数字集合
      dataArr: [
        {
          type: 1, // 类型为1表示归零 类型为2表示计算符号 类型为3表示删除 类型为4表示数字
          text: "C",
        },
        {
          type: 5,
          text: "+/-",
        },
        {
          type: 5,
          text: "%",
        },
        {
          type: 3,
          text: "←",
        },
        {
          type: 4,
          text: "7",
        },
        {
          type: 4,
          text: "8",
        },
        {
          type: 4,
          text: "9",
        },
        {
          type: 2,
          text: "×²",
        },
        {
          type: 5,
          text: "√",
        },
        {
          type: 4,
          text: "4",
        },
        {
          type: 4,
          text: "5",
        },
        {
          type: 4,
          text: "6",
        },
        {
          type: 2,
          text: "×",
        },
        {
          type: 2,
          text: "÷",
        },
        {
          type: 4,
          text: "1",
        },
        {
          type: 4,
          text: "2",
        },
        {
          type: 4,
          text: "3",
        },
        {
          type: 2,
          text: "+",
        },
        {
          type: 2,
          text: "-",
        },
        {
          type: 4,
          text: "0",
        },
        {
          type: 4,
          text: ".",
        },
        {
          type: 2,
          text: "=",
        },
      ],
    };
  },
  methods: {
    btnClick(item) {
      // 点击c数字规0
      if (item.type === 1) {
        this.inputValue = "0";
        return;
      }
      // 类型为5的功能暂时不做
      if (item.type === 5) {
        return;
      }
      // 当没有值或者值为 点击符号不起作用
      if (this.inputValue.length === "") {
        if (item.type === "2") return;
      }
      // 当值是0是点击数字将0转化为点击的数字
      if (this.inputValue === "0" && item.type === 4) {
        this.inputValue = item.text;
        return;
      }
      // 点击删除删除一位数字

      [];
      if (item.type === 3 && this.inputValue.length > 0) {
        this.inputValue = this.inputValue.slice(0, this.inputValue.length - 1);
        return;
      }
      // 检测最后一位是否是数字 不是数字则点击符号无效
      let flag = /[0-9]/.test(this.inputValue[this.inputValue.length - 1]);
      // 如果最后一位是符号 继续点击符号无效
      if (item.type === 2 && !flag) {
        return;
      } else {
        // 点击删除 如果内容为空则无效
        if (item.type === 3 && this.inputValue === "") {
          return;
        }
        if (item.text !== "=") {
          this.inputValue += item.text;
        } else {
          this.calcFn(this.inputValue);
        }
      }
    },
    calcFn(value) {
      // 将获得的值
      this.numArr = value.split(/[+|\-|×|÷]/);
      this.arr = value.match(/[+|\-|×|÷]/g);
    },
    arrFn(i) {
      this.arr.splice(i, 1);
      this.numArr[i] = this.inputValue;
      this.numArr.splice(i + 1, 1);
    },
    add(arg1, arg2) {
      (arg1 = arg1.toString()), (arg2 = arg2.toString()); // 将传入的数据转化为字符串
      var arg1Arr = arg1.split("."), // 将小数的数据从小数点的位置拆开
        arg2Arr = arg2.split("."),
        d1 = arg1Arr.length == 2 ? arg1Arr[1] : "", // 获取第一个数的小数点的长度
        d2 = arg2Arr.length == 2 ? arg2Arr[1] : ""; // 获取第二个数的小数点的长度
      var maxLen = Math.max(d1.length, d2.length); // 获取小数点长度较大的值
      var m = Math.pow(10, maxLen); // 这里表示10的小数点长度次方 也就是说如果小数点长度为2 m的值就是100 如果小数点长度是3 m的值就是1000如果不懂请自行查找api
      var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen)); // 将小数转化为整数后相加在除掉两个数乘过的倍数然后去小数点较长的长度的小数位数
      var d = arguments[2]; // 第三个参数用户可以自行决定是否要传递 用来定义要保留的小数长度
      return typeof d === "number" ? Number(result.toFixed(d)) : result;
    },
    sun(arg1, arg2) {
      return this.add(arg1, -arg2);
    },
    mul(arg1, arg2) {
      var r1 = arg1.toString(), // 将传入的数据转化为字符串
        r2 = arg2.toString(),
        m,
        resultVal,
        d = arguments[2];
      m =
        (r1.split(".")[1] ? r1.split(".")[1].length : 0) +
        (r2.split(".")[1] ? r2.split(".")[1].length : 0); // 获取两个数字的小数位数的和
      // 乘积的算法就是去掉小数点做整数相乘然后除去10的所有小数位的次方
      resultVal =
        (Number(r1.replace(".", "")) * Number(r2.replace(".", ""))) /
        Math.pow(10, m);

      return typeof d !== "number"
        ? Number(resultVal)
        : Number(resultVal.toFixed(parseInt(d)));
    },

    div(arg1, arg2) {
      var r1 = arg1.toString(),
        r2 = arg2.toString(),
        m,
        resultVal,
        d = arguments[2];
      m =
        (r2.split(".")[1] ? r2.split(".")[1].length : 0) -
        (r1.split(".")[1] ? r1.split(".")[1].length : 0);
      resultVal =
        (Number(r1.replace(".", "")) / Number(r2.replace(".", ""))) *
        Math.pow(10, m);
      return typeof d !== "number"
        ? Number(resultVal)
        : Number(resultVal.toFixed(parseInt(d)));
    },
  },
  watch: {
    arr() {
      for (var i = 0; i < this.arr.length; i++) {
        let j = this.arr.indexOf("×");
        let d = this.arr.indexOf("÷");
        if (j !== -1) {
          if (this.arr[i] == "×") {
            this.inputValue = this.mul(
              this.numArr[i],
              this.numArr[i + 1]
            ).toString();
            this.arrFn(i);
            return;
          }
        } else {
          if (d !== -1) {
            if (this.arr[i] == "÷") {
              this.inputValue = this.div(
                this.numArr[i],
                this.numArr[i + 1]
              ).toString();
              this.arrFn(i);
              return;
            }
          } else {
            if (this.arr[i] == "+") {
              this.inputValue = this.add(
                this.numArr[i],
                this.numArr[i + 1]
              ).toString();
              this.arrFn(i);
              return;
            }

            if (this.arr[i] == "-") {
              this.inputValue = this.sun(
                this.numArr[i],
                this.numArr[i + 1]
              ).toString();
              this.arrFn(i);
              return;
            }
          }
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
#app {
  width: 400px;
  margin: 100px auto;
  border: 1px solid silver;
  height: 500px;
}
ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 20px;
}

.calc-box {
  width: 300px;
  padding: 10px;
  border: 1px solid #ccc;
  margin: 100px auto;
}

.calc-box input {
  width: 92%;
  line-height: 40px;
  border: 1px solid #ccc;
  text-align: right;
  padding: 0 10px;
}

li {
  margin-right: 10px;
  margin-top: 10px;
}

li:nth-child(5n-1),
li:nth-child(22) {
  margin-right: 0;
}

li:nth-child(4) button,
li:nth-child(20) button,
li:nth-child(22) button {
  width: 102px;
}

li button {
  width: 46px;
  height: 46px;
}
</style>